package com.och.mrcp.config;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.Executor;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * 性能优化配置类
 * 提供线程池、连接池、限流等高并发支持配置
 */
@Configuration
@ConfigurationProperties(prefix = "performance")
@Data
public class PerformanceConfig {
    
    // 线程池配置
    private ThreadPoolProperties threadPool = new ThreadPoolProperties();
    
    // 连接池配置
    private ConnectionPoolProperties connectionPool = new ConnectionPoolProperties();
    
    // 限流配置
    private RateLimitProperties rateLimit = new RateLimitProperties();
    
    // 缓存配置
    private CacheProperties cache = new CacheProperties();
    
    /**
     * 异步任务线程池
     */
    @Bean("asyncTaskExecutor")
    public Executor asyncTaskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(threadPool.getCoreSize());
        executor.setMaxPoolSize(threadPool.getMaxSize());
        executor.setQueueCapacity(threadPool.getQueueCapacity());
        executor.setKeepAliveSeconds(threadPool.getKeepAliveSeconds());
        executor.setThreadNamePrefix("AsyncTask-");
        executor.setWaitForTasksToCompleteOnShutdown(true);
        executor.setAwaitTerminationSeconds(60);
        
        // 拒绝策略：调用者运行策略
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        
        executor.initialize();
        return executor;
    }
    
    /**
     * MRCP处理线程池
     */
    @Bean("mrcpExecutor")
    public Executor mrcpExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(threadPool.getCoreSize() / 2);
        executor.setMaxPoolSize(threadPool.getMaxSize() / 2);
        executor.setQueueCapacity(threadPool.getQueueCapacity());
        executor.setKeepAliveSeconds(threadPool.getKeepAliveSeconds());
        executor.setThreadNamePrefix("MRCP-");
        executor.setWaitForTasksToCompleteOnShutdown(true);
        executor.setAwaitTerminationSeconds(60);
        
        // 拒绝策略：丢弃最老的任务
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardOldestPolicy());
        
        executor.initialize();
        return executor;
    }
    
    /**
     * 语音处理线程池
     */
    @Bean("voiceExecutor")
    public Executor voiceExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(threadPool.getCoreSize());
        executor.setMaxPoolSize(threadPool.getMaxSize());
        executor.setQueueCapacity(threadPool.getQueueCapacity() * 2); // 语音处理队列更大
        executor.setKeepAliveSeconds(threadPool.getKeepAliveSeconds());
        executor.setThreadNamePrefix("Voice-");
        executor.setWaitForTasksToCompleteOnShutdown(true);
        executor.setAwaitTerminationSeconds(120); // 语音处理需要更长的等待时间
        
        // 拒绝策略：阻塞策略
        executor.setRejectedExecutionHandler(new RejectedExecutionHandler() {
            @Override
            public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
                if (!executor.isShutdown()) {
                    try {
                        // 阻塞等待队列有空位
                        executor.getQueue().put(r);
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                        throw new RuntimeException("Task interrupted", e);
                    }
                }
            }
        });
        
        executor.initialize();
        return executor;
    }
    
    @Data
    public static class ThreadPoolProperties {
        private int coreSize = 16;
        private int maxSize = 64;
        private int queueCapacity = 1000;
        private int keepAliveSeconds = 60;
    }
    
    @Data
    public static class ConnectionPoolProperties {
        private int initialSize = 10;
        private int maxActive = 100;
        private int maxIdle = 20;
        private int minIdle = 5;
        private int validationTimeout = 5000;
    }
    
    @Data
    public static class RateLimitProperties {
        private boolean enable = true;
        private int permitsPerSecond = 1000;
        private int burstCapacity = 2000;
    }
    
    @Data
    public static class CacheProperties {
        private boolean enable = true;
        private int maxEntries = 10000;
        private int expireAfterWrite = 300;
        private int expireAfterAccess = 600;
    }
}
